import useTokenStore from '@/vendors/store/token'
import useUserInfo from './vendors/store/user'
import axios from 'axios'
import qs from 'qs'
import { message, MessageType } from '@/components/message/message'
import router from './router'
const pendingRequest = new Map()
const generateRequestKey = (config: any) => {
  const { url, method, data, params } = config
  const key = [url, method, JSON.stringify(data), JSON.stringify(params)].join('&')
  return key
}
const addPendingRequest = (config: any) => {
  const key = generateRequestKey(config)
  if (!pendingRequest.has(key)) {
    config.cancelToken = new axios.CancelToken(cancel => {
      pendingRequest.set(key, cancel)
    })
  }
}
const removePendingRequest = (config: any) => {
  const key = generateRequestKey(config)
  if (pendingRequest.has(key)) {
    const cancel = pendingRequest.get(key)
    cancel(key)
    pendingRequest.delete(key)
  }
}
const https = axios.create({
  // baseURL: import.meta.env.VITE_APP_BASE_API,
  baseURL: 'api',
  timeout: 5000

})
// 请求拦截器
https.interceptors.request.use(
  (config: any) => {
    // 添加请求头
    const tokenStore = useTokenStore()
    config.headers.authorization = 'Bearer ' + tokenStore.getToken
    let data = []
    if (config.data && config.data.indexOf('&') > -1) {
      data = config.data.split('&')
    } else if (config.data) {
      data[0] = config.data
    }
    config.data = data.join('&')
    config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
    removePendingRequest(config)
    addPendingRequest(config)
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)
// 响应拦截器
https.interceptors.response.use(
  (res) => {
    removePendingRequest(res.config)
    const tokenStore = useTokenStore()
    const userStore = useUserInfo()
    if ((res.data as any).code === 202) {
      tokenStore.clearToken()
      userStore.clearUserInfo()
      // message('login expired and please login again', MessageType.error)
      router.replace({
        path: '/login'
      })
      return { 'code': 202, 'message': 'login expired and please login again' }
    } else if ((res.data as any).code === 203) {
      tokenStore.clearToken()
      userStore.clearUserInfo()
      // message('Another user logins and current access is not effective', MessageType.info)
      router.replace({
        path: '/login'
      })
      return { 'code': 203, 'message': 'Another user logins and current access is not effective' }
    } else {
      return res.data
    }

  },
  (error) => {
    removePendingRequest(error.config || {})
    return Promise.reject(error)
  }
)

// POST
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function fetchPost(url: string, params: any) {
  return new Promise((resolve, reject) => {
    https
      .post(url, qs.stringify(params))
      .then(
        (response) => {
          if ((response as any).code === 200) {
            resolve(response)
          } else {
            message((response as any).message, MessageType.error)
            // eslint-disable-next-line prefer-promise-reject-errors
            reject('出错啦....')
          }
          resolve(response)
        },
        (err) => {
          // message(err, MessageType.error)
          reject(err)
        }
      )
      .catch((error) => {
        message(error, MessageType.error)
        reject(error)
      })
  })
}
function fetchGet(url: string, params: any) {
  return new Promise((resolve, reject) => {
    https
      .get(url, { params })
      .then(
        (response) => {
          if ((response as any).code === 200) {
            resolve(response)
          } else {
            message((response as any).message, MessageType.error)
            // eslint-disable-next-line prefer-promise-reject-errors
            reject('出错啦....')
          }
        },
        (err) => {
          // message(err, MessageType.error)
          reject(err)
        }
      )
      .catch((error) => {
        message(error, MessageType.error)
        reject(error)
      })
  })
}
function fetchPatch(url: string, params: any) {
  return new Promise((resolve, reject) => {
    https
      .patch(url, qs.stringify(params))
      .then(
        (response) => {
          if ((response as any).code === 200) {
            resolve(response)
          } else {
            // message((response as any).message, MessageType.error)
            // eslint-disable-next-line prefer-promise-reject-errors
            reject('出错啦....')
          }
        },
        (err) => {
          reject(err)
        }
      )
      .catch((error) => {
        reject(error)
      })
  })
}

const http = {
  fetchPost,
  fetchGet,
  fetchPatch
}
export default http
